package api

import (
	"TaskAssignmentSystem/internal/admin/services"
	"TaskAssignmentSystem/internal/pkg/middleware/handler"
	Redis "TaskAssignmentSystem/pkg/db/redis"
	"TaskAssignmentSystem/pkg/utils"
	"fmt"
	"github.com/iris-contrib/middleware/jwt"
	jsoniter "github.com/json-iterator/go"
	"github.com/kataras/iris/v12"
	"strings"
)

/*
 *  LoginRequest
 *  @Description: 登录请求参数
 */

type LoginRequest struct {
	UserName string `json:"user_name" validate:"required"`
	PassWord string `json:"pass_word" validate:"required"`
}

// @Summary 登录
// @Description 后台管理系统登录
// @Tags 登录
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @Param param body LoginRequest true "后台管理系统登录参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/login [post]
func AdminLoginHandler(ctx iris.Context) {
	var RequestParams LoginRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	remoteAddr := ctx.Request().RemoteAddr

	var adminServe services.SystemAdminService
	if response, err := adminServe.Login(RequestParams.UserName, RequestParams.PassWord, remoteAddr); err != nil {
		ctx.JSON(utils.ResponseError{
			Code:    iris.StatusInternalServerError,
			Message: err.Error(),
		})
		return
	} else {
		ctx.JSON(utils.Response{
			Code:    200,
			Message: "ok",
			Data:    response,
		})
		return
	}
}

func AdminLogoutHandler(ctx iris.Context) {
	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	var adminServe services.SystemAdminService
	if err := adminServe.Logout(claims.Id); err != nil {
		ctx.JSON(utils.ResponseServerError(err))
		return
	} else {
		ctx.JSON(utils.ResponseOK())
		return
	}
}

/*
 *  EditAdminSelfPassWordRequest
 *  @Description: 编辑管理员密码请求参数
 */

type EditAdminSelfPassWordRequest struct {
	OlePassWord string `json:"ole_pass_word" validate:"required"`
	NewPassWord string `json:"new_pass_word" validate:"required"`
}

// @Summary 更新管理员密码
// @Description 管理员更新自己的密码
// @Tags 管理员
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body EditAdminSelfPassWordRequest true "更新管理员密码参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/system_admin/change_password [post]
func AdminChangPassWordHandler(ctx iris.Context) {
	var RequestParams EditAdminSelfPassWordRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	var systemAdminServe services.SystemAdminService
	if err := systemAdminServe.UpdatePassWord(claims.Id, RequestParams.OlePassWord, map[string]interface{}{"pass_word": utils.MD5(RequestParams.NewPassWord)}); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: 200, Message: "ok", Data: "ok"})
		return
	}
}

/*
 * AuthenticatedHandler
 * @Description: 验证token信息的中间件
 * @param ctx
 */

func AuthenticatedHandler(ctx iris.Context) {
	var i services.AuthServiceInterface
	//获取动态userId 设备信息
	var claims services.CustomClaims
	authHeader, err := jwt.FromAuthHeader(ctx)
	split := strings.Split(authHeader, ".")
	if err != nil {
		ctx.JSON(iris.Map{"code": iris.StatusUnauthorized, "message": err.Error()})
		return
	}
	base64Decode, err := utils.Base64Decode(split[1])
	client := Redis.RedisGClient
	jsoniter.Unmarshal([]byte(base64Decode), &claims)
	var userSecret string
	if strings.Contains(ctx.FullRequestURI(), "/api/app") {
		userSecret = client.Get(fmt.Sprintf("user_token_%d", claims.Id)).Val()
	} else {
		userSecret = client.Get(fmt.Sprintf("admin_token_%d", claims.Id)).Val()
	}

	i = &services.CustomClaims{AppSecret: []byte(userSecret)}
	if err := i.VerificationToken(ctx); err != nil {
		return
	}
	ctx.Next()
}
